package com.mrd.frame.onlinepay.notify;

import java.io.BufferedOutputStream;
import java.io.IOException;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSONObject;
import com.alipay.api.internal.util.AlipaySignature;
import com.mrd.frame.attachment.AttachmentService;
import com.mrd.frame.domain.AccessConfig;
import com.mrd.frame.domain.NoticeMessage;
import com.mrd.frame.domain.Order;
import com.mrd.frame.domain.OrderInteraction;
import com.mrd.frame.domain.TradeStatement;
import com.mrd.frame.redis.JedisClientClusterImpl;
import com.mrd.frame.service.AccessConfigService;
import com.mrd.frame.service.OrderInteractionService;
import com.mrd.frame.service.OrderService;
import com.mrd.frame.service.TradeStatementService;
import com.mrd.weixinpay.util.AliPayUtil;
import com.mrd.weixinpay.util.Constents;
import com.mrd.weixinpay.util.HttpUtil;
import com.mrd.weixinpay.util.PayCommonUtil;
import com.thoughtworks.xstream.XStream;

@Component
public class AliNotify {
	private static final Logger logger = Logger.getLogger(AliNotify.class);
	@Autowired
	private JedisClientClusterImpl jedisClientClusterImpl;
    @Autowired
    private AttachmentService attachmentService;
    
	public String excute(OrderService orderService,
			TradeStatementService tradeStatementService,
			OrderInteractionService orderInteractionService,
			AccessConfigService accessConfigService, 
			Map<String, String[]> requestParams)
			throws Exception {
		String message = "";
		String outTradeNo = "";
		try {
			Order order = new Order();
			AccessConfig accessConfig = new AccessConfig();
			TradeStatement tradeStatement = new TradeStatement();
			OrderInteraction orderInter = new OrderInteraction();
			Map<String, String> notifyMap = new HashMap<String, String>();
			notifyMap = AliPayUtil.parseNotifyMsg(requestParams);
			logger.info("回掉参数:"+notifyMap);
			String mch_id = "";
			String orderId = notifyMap.get("out_trade_no");
			order = orderService.selectByPrimaryKey(orderId);
			outTradeNo = order.getTradeNo();// 商家订单号
			String total_fee =  notifyMap.get("total_amount");// 支付订单金额
			String time_end =  notifyMap.get("notify_time");
			String trade_status =  notifyMap.get("trade_status");// 交易状态
			// 将微信的通知信息返回给业务系统
			accessConfig = accessConfigService.selectByUserKeyAndPayChannel(
					order.getUserKey(), order.getPayChannel());
			String paramXml = PayCommonUtil.MapToXml(notifyMap);

			String publicKey = accessConfig.getPublicKey();// 密钥（要动态读取）
			boolean verify_result = AlipaySignature.rsaCheckV1(notifyMap, accessConfig.getAlipayPublicKey(),
					"UTF-8", (String) notifyMap.get("sign_type"));
			int totalAli  = new BigDecimal(total_fee).multiply(new BigDecimal(100)).intValue();

			logger.info(order.getTotalAmount()+":"+totalAli);
			// 判断签名是否正确,判断返回的金额是否和订单中的一致
			if (verify_result
					&& order.getTotalAmount()==totalAli && !trade_status.equals("WAIT_BUYER_PAY")) {
				logger.info("验证通过");
				if ("TRADE_SUCCESS".equals(trade_status)) {// 交易状态为交易支付成功
					logger.info("处理交易成功逻辑");
					// 更新订单表中的订单状态，通知而业务系统,将此信息存入资金流水表，将此信息存入交互记录表
					SimpleDateFormat formate = new SimpleDateFormat(
							"yyyyMMddHHmmss");
					Date date = formate.parse(time_end);

					// 更新订单表
					if (!"2".equals(order.getStatus())) {
						order.setStatus("2");
						order.setThirdOrderId("");
						orderService.updateByPrimaryKeySelective(order);
						logger.info("更新订单状态");
					}

					// 存入资金流水表
					tradeStatement.setOrderId(orderId);
					List<TradeStatement> trade = new ArrayList<>();
					trade = tradeStatementService
							.selectSelective(tradeStatement);
					if (!(trade.size() > 0)) {
						tradeStatement.setOrderId(orderId);
						tradeStatement.setPayChannel("2");
						tradeStatement.setThirdOrderId("");
						tradeStatement.setTotalAmount(totalAli);
						tradeStatement.setTradeNo(outTradeNo);
						tradeStatement.setTradeTime(date);
						tradeStatement.setTradeType("1");
						tradeStatement.setTradingStatementsId(String
								.valueOf(System.currentTimeMillis()));
						tradeStatement.setUserKey(order.getUserKey());
						tradeStatementService.insert(tradeStatement);
						logger.info("插入资金流水");
					}

					// 将第三方返回给服务端的信息存入交互记录表
					orderInter.setOrderId(orderId);
					orderInter.setType("A5");
					List<OrderInteraction> ordeInts = new ArrayList<>();
					ordeInts = orderInteractionService
							.selectSelective(orderInter);

					if (ordeInts==null) {
						orderInter.setCreateTime(new Date());
						orderInter.setOrderInteractionId(String.valueOf(System
								.currentTimeMillis()));
						orderInter.setParameters(paramXml);
						orderInter.setStatus("0");
						int a5 = orderInteractionService.insert(orderInter);
					}

					// A7：server给client的支付结果， A8：client给server的收到支付结果反馈，
					OrderInteraction ordInt = new OrderInteraction();
					ordInt.setOrderId(orderId);
					ordInt.setType("A8");
					ordInt.setStatus("0");
					List<OrderInteraction> ordInts = new ArrayList<>();
					ordeInts = orderInteractionService
							.selectSelective(orderInter);
					
					if (ordInts!=null) {
						Map<String, Object> map = new HashMap<>();
						map.put("orderId", orderId);
						map.put("time_end", time_end);
						map.put("transaction_id", "");
						map.put("outTradeNo", outTradeNo);
						map.put("total_fee", totalAli);
						map.put("status", "SUCCESS");
						JSONObject json = new JSONObject(map);
						String retStatus = "FAILURE";
						try {
							logger.info("开始异步通知支付客户端");
							retStatus = HttpUtil.postData(
									accessConfig.getNotifyUrl(),
									json.toString(), null);
							logger.info("异步通知支付客户端结束");
//							JSONObject retJSON = JSONObject.parseObject(rs);
//							String retStatus = retJSON.getString("status");
							// 服务端发送回调信息给业务系统存入交互表中
							ordInt.setCreateTime(new Date());
							ordInt.setOrderInteractionId(String.valueOf(System
									.currentTimeMillis()));
							ordInt.setStatus("0");
							ordInt.setType("A7");
							ordInt.setParameters(json.toString());
							int a7 = orderInteractionService.insert(ordInt);

							if ("SUCCESS".equals(retStatus)) {
								// 客户端返回成功信息存储到交互记录表
								ordInt.setCreateTime(new Date());
								ordInt.setOrderInteractionId(String
										.valueOf(System.currentTimeMillis()));
								ordInt.setParameters(retStatus);
							} else {
								NoticeMessage noticeMsg = new NoticeMessage( orderId, time_end, "", outTradeNo,
										totalAli+"", "SUCCESS", order.getUserKey(), accessConfig.getNotifyUrl());
								jedisClientClusterImpl.set(Constents.PAYNOTICEINDEX+noticeMsg.getOrderId(), noticeMsg, new Long(120), TimeUnit.MINUTES);
								// 客户端反馈不成功，此时进行标记以便后续消息重发
								ordInt.setCreateTime(new Date());
								ordInt.setOrderInteractionId(String
										.valueOf(System.currentTimeMillis()));
								ordInt.setParameters(retStatus);
								ordInt.setStatus("1");
							}
							int a8 = orderInteractionService.insert(ordInt);
						} catch (Exception e) {

						}

					}
	    			//清理对应的图片
	    			attachmentService.delete(order.getOrderId());
					logger.info("支付成功");
					// 通知微信.异步确认成功.必写.不然会一直通知后台.八次之后就认为交易失败了.
					message = "success";

				} else {

					// 吊起查询接口,将支付失败的信息通知给业务系统,将此信息存入交互记录表,
					Map<String, Object> map = new HashMap<>();
					map.put("orderId", orderId);
					map.put("time_end", time_end);
					map.put("transaction_id", "");
					map.put("outTradeNo", outTradeNo);
					map.put("total_fee", totalAli);

					if ("TRADE_SUCCESS".equals(trade_status)) {
						// 此订单完成支付
						map.put("status", "FAIL");
					} else {
						map.put("status", "FAIL");
					}
					JSONObject json = new JSONObject(map);
					// 发送信息给业务系统
					OrderInteraction ordInt = new OrderInteraction();
					String retStatus = "FAILURE";
					try {
						retStatus = HttpUtil.postData(
								accessConfig.getNotifyUrl(), json.toString(),
								null);

						// 服务端发送回调信息给业务系统存入交互表中
						ordInt.setCreateTime(new Date());
						ordInt.setOrderInteractionId(String.valueOf(System
								.currentTimeMillis()));
						ordInt.setStatus("0");
						ordInt.setType("A7");
						ordInt.setParameters(json.toString());
						int a7 = orderInteractionService.insert(ordInt);

						if ("SUCCESS".equals(retStatus)) {
							// 客户端返回成功信息存储到交互记录表
							ordInt.setCreateTime(new Date());
							ordInt.setOrderInteractionId(String.valueOf(System
									.currentTimeMillis()));
							ordInt.setParameters(retStatus);
						} else {
							// 客户端反馈不成功，此时进行标记以便后续消息重发
							NoticeMessage noticeMsg = new NoticeMessage( orderId, time_end, "", outTradeNo,
									totalAli+"", retStatus, order.getUserKey(), accessConfig.getNotifyUrl());
							jedisClientClusterImpl.set(Constents.PAYNOTICEINDEX+noticeMsg.getOrderId(), noticeMsg, new Long(120), TimeUnit.MINUTES);
							ordInt.setCreateTime(new Date());
							ordInt.setOrderInteractionId(String.valueOf(System
									.currentTimeMillis()));
							ordInt.setParameters(retStatus);
							ordInt.setStatus("1");
						}
						int a8 = orderInteractionService.insert(ordInt);
					} catch (Exception e) {

					} 
					orderInter.setCreateTime(new Date());
					orderInter.setOrderInteractionId(String.valueOf(System
							.currentTimeMillis()));
					orderInter.setStatus("0");
					orderInter.setType("A6");
					orderInter.setParameters(new JSONObject(map).toString());
					int a6 = orderInteractionService.insert(orderInter);

					logger.info("支付失败,错误信息：" + paramXml);
					message = "failure";

				}
			} else if(trade_status.equals("WAIT_BUYER_PAY")){
				logger.info("订单生成，待支付");
			}else {
				// 不需要做处理，等待微信再次通知
				logger.info("通知签名验证失败");
			}

		} catch(Exception ex){
			ex.printStackTrace();
		}
		return message;
	}

}
